﻿using System;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Windows.Markup;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Controls.Primitives;

namespace EasySL.Controls
{
    public abstract class ExDataGridColumn : DataGridTemplateColumn
    {

        #region BindProperty
        /// <summary>
        /// Identifies the BindProperty dependency property.
        /// </summary>
        public static readonly DependencyProperty BindPropertyProperty =
            DependencyProperty.Register("BindProperty",
                typeof(string),
                typeof(ExDataGridColumn),
                new PropertyMetadata((d, e) =>
                    {
                        var column = d as ExDataGridColumn;
                        column.CellTemplate = column.CreateDataTemplate(e.NewValue.ToString());
                    })
                );
                

        /// <summary>
        /// Gets or sets BindProperty.
        /// </summary>
        public string BindProperty
        {
            get { return (string)GetValue(BindPropertyProperty); }
            set { SetValue(BindPropertyProperty, value); }
        }
        #endregion

        #region HeaderText
        /// <summary>
        /// Identifies the HeaderText dependency property.
        /// </summary>
        public static readonly DependencyProperty HeaderTextProperty =
            DependencyProperty.Register("HeaderText",
                typeof(string),
                typeof(ExDataGridColumn),
                new PropertyMetadata((d, e) =>
                {
                    var column = d as ExDataGridColumn;
                    column.Header = e.NewValue;
                })
                );


        /// <summary>
        /// Gets or sets HeaderText.
        /// </summary>
        public string HeaderText
        {
            get { return (string)GetValue(HeaderTextProperty); }
            set { SetValue(HeaderTextProperty, value); }
        }
        #endregion

        #region EnableFilter
        /// <summary>
        /// Identifies the EnableFilter dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableFilterProperty =
            DependencyProperty.Register("EnableFilter",
                typeof(bool),
                typeof(ExDataGridColumn),
                new PropertyMetadata(true)
                );

        /// <summary>
        /// Gets or sets EnableFilter.
        /// </summary>
        public bool EnableFilter
        {
            get { return (bool)GetValue(EnableFilterProperty); }
            set { SetValue(EnableFilterProperty, value); }
        }
        #endregion   
       	
        #region EnableSort
        /// <summary>
        /// Identifies the EnableSort dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableSortProperty =
            DependencyProperty.Register("EnableSort",
                typeof(bool),
                typeof(ExDataGridColumn),
                new PropertyMetadata(true)
                );

        /// <summary>
        /// Gets or sets EnableSort.
        /// </summary>
        public bool EnableSort
        {
            get { return (bool)GetValue(EnableSortProperty); }
            set { SetValue(EnableSortProperty, value); }
        }
        #endregion 

        #region EnableDelete
        /// <summary>
        /// Identifies the EnableDelete dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableDeleteProperty =
            DependencyProperty.Register("EnableDelete",
                typeof(bool),
                typeof(ExDataGridColumn),
                new PropertyMetadata(false)
                );

        /// <summary>
        /// Gets or sets EnableDelete.
        /// </summary>
        public bool EnableDelete
        {
            get { return (bool)GetValue(EnableDeleteProperty); }
            set { SetValue(EnableDeleteProperty, value); }
        }
        #endregion

        #region EnableExpand
        /// <summary>
        /// Identifies the EnableExpand dependency property.
        /// </summary>
        public static readonly DependencyProperty EnableExpandProperty =
            DependencyProperty.Register("EnableExpand",
                typeof(bool),
                typeof(ExDataGridColumn),
                new PropertyMetadata(false)
                );

        /// <summary>
        /// Gets or sets EnableExpand.
        /// </summary>
        public bool EnableExpand
        {
            get { return (bool)GetValue(EnableExpandProperty); }
            set { SetValue(EnableExpandProperty, value); }
        }
        #endregion 

        #region ShowOrderNumber
        /// <summary>
        /// Identifies the ShowOrderNumber dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowOrderNumberProperty =
            DependencyProperty.Register("ShowOrderNumber",
                typeof(bool),
                typeof(ExDataGridColumn),
                new PropertyMetadata(false)
                );

        /// <summary>
        /// Gets or sets ShowOrderNumber.
        /// </summary>
        public bool ShowOrderNumber
        {
            get { return (bool)GetValue(ShowOrderNumberProperty); }
            set { SetValue(ShowOrderNumberProperty, value); }
        }
        #endregion

        #region Parent
        public string Parent
        {
            get { return (string)GetValue(ParentProperty); }
            set { SetValue(ParentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Parent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ParentProperty =
            DependencyProperty.Register("Parent", typeof(string), typeof(ExDataGridColumn), null);
        #endregion

        #region BackGround
        public SolidColorBrush BackGround
        {
            get { return (SolidColorBrush)GetValue(BackGroundProperty); }
            set { SetValue(BackGroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BackGround.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BackGroundProperty =
            DependencyProperty.Register("BackGround", typeof(SolidColorBrush), typeof(ExDataGridColumn), new PropertyMetadata(null));
        #endregion

        #region ToolTip
        public object ToolTip
        {
            get { return (object)GetValue(ToolTipProperty); }
            set { SetValue(ToolTipProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ToolTip.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ToolTipProperty =
            DependencyProperty.Register("ToolTip", typeof(object), typeof(ExDataGridColumn), new PropertyMetadata(null));
        #endregion



        public ExFilterAction CurrentFilterAction { get; set; }
        public ExFilterValue CurrentFilterValue { get; set; }
        public event EventHandler<DataRowEventArgs> Click;
        
        public ExDataGridColumn()
            : base()
        {
            this.IsReadOnly = true;
        }

        protected virtual DataTemplate CreateDataTemplate(string value)
        {
            string converterName = this.Converter.GetType().Name;

            this.AddConverterResource(converterName, this.Converter);

            string xaml = string.Format(this.DataTemplate, "Data", converterName, value, value + "_Order", this.TextAlignment);

            DataTemplate exDataTemplate = (DataTemplate)XamlReader.Load(xaml);

            return exDataTemplate;
        }

        protected virtual IValueConverter Converter
        {
            get
            {
                return new ExStringConverter();
            }
        }

        public virtual ExFilterType FilterType
        {
            get
            {
                return ExFilterType.String;
            }
        }

        public virtual TextAlignment TextAlignment
        {
            get
            {
                return TextAlignment.Right;
            }
        }

        protected virtual string DataTemplate
        {
            get
            {
                return dataTemplate;
            }
        }

        protected void AddConverterResource(string key, object value)
        {
            var resources = Application.Current.Resources;
            if (!resources.Contains(key))
                resources.Add(key, value);
        }

        public void InitDataGridCellClickEvent(DataGridRow row)
        {
            if (this.Click == null)
                return;

            var cellContent = this.GetCellContent(row) as FrameworkElement;
            if (cellContent != null && cellContent.FindName("content") != null)
            {
                var content = cellContent.FindName("content") as FrameworkElement;
                content.Cursor = Cursors.Hand;

                if (content is ButtonBase)
                    (content as ButtonBase).Click += (s, e) => DataGridCellClick(s);
                else
                    content.MouseLeftButtonDown += (s, e) => DataGridCellClick(s);
            }
        }

        private void DataGridCellClick(object sender)
        {
            var content = sender as FrameworkElement;
            var dataRow = content.DataContext as DataRow;
            var tag = content.Tag.ToString();

            this.OnClick(dataRow);
        }

        private void OnClick(DataRow dataRow)
        {
            if (this.Click != null)
                this.Click(this, new DataRowEventArgs() { Data = dataRow });
        }

        private readonly string dataTemplate = 
            "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">"
            +"<Grid Margin=\"2\">"
            + "<Grid.ColumnDefinitions><ColumnDefinition Width=\"5\"/><ColumnDefinition/><ColumnDefinition Width=\"8\"/><ColumnDefinition Width=\"auto\" MinWidth=\"15\"/></Grid.ColumnDefinitions>"
            + "<TextBlock Name=\"content\" Tag=\"{2}\" DataContext=\"{{Binding}}\" Grid.Column=\"1\" VerticalAlignment=\"Center\" TextAlignment=\"{4}\" Text=\"{{Binding {0}" 
            + ", Converter={{StaticResource {1}}}"
            +", ConverterParameter='{2}'}}\"/> "
            + "<TextBlock Grid.Column=\"3\" FontSize=\"9\" VerticalAlignment=\"Center\" Foreground=\"#b9b9b9\" TextAlignment=\"Right\" Text=\"{{Binding {0}"
            + ", Converter={{StaticResource ExNumberConverter}}"
            + ", ConverterParameter='{3}'}}\"/> "
            +"</Grid>"
            +"</DataTemplate>";
    }

    public class DataRowEventArgs : EventArgs
    {
        public DataRow Data { get; set; }
    }
}
